C语言实现GB2312和UTF8之间的编码转换 您所在的位置:网站首页 c语言 linux utf8 gbk互转 C语言实现GB2312和UTF8之间的编码转换

C语言实现GB2312和UTF8之间的编码转换

2024-07-09 17:10| 来源: 网络整理| 查看: 265

C语言实现GB2312和UTF8之间的编码转换

GB2312

GB2312编码适用于汉字处理、汉字通信等系统之间的信息交换,基本集共收入汉字6763个和非汉字图形字符682个。GB2312中对所收汉字进行了“分区”处理,字符集分成94个区,每区含有94个汉字/符号,这种表示方式也称为区位码。 01-09区为特殊符号。 16-55区为一级汉字,按拼音排序。 56-87区为二级汉字,按部首/笔画排序。 10-15区及88-94区则未有编码。 举例来说,“啊”字是GB2312之中的第一个汉字,它的区位码就是1601。每个汉字及符号以两个字节来表示。第一个字节称为“高位字节”(也称“区字节)”,第二个字节称为“低位字节”(也称“位字节”)。

UTF-8

UTF-8(8位元,Universal Character Set/Unicode Transformation Format)是针对Unicode的一种可变长度字符编码。UTF-8使用1~4字节为每个字符编码: 1)一个US-ASCIl字符只需1字节编码(Unicode范围由U+0000~U+007F)。 2)带有变音符号的拉丁文、希腊文、西里尔字母、亚美尼亚语、希伯来文、阿拉伯文、叙利亚文等字母则需要2字节编码(Unicode范围由U+0080~U+07FF)。 3)其他语言的字符(包括中日韩文字、东南亚文字、中东文字等)包含了大部分常用字,使用3字节编码。 4)其他极少使用的语言字符使用4字节编码。

由此可知,对于中文,GB2312编码占用2个字节,UTF-8编码占用3个字节。

linux下编码工具

命令行工具 iconv -f encoding -t encoding inputfile

有如下选项可用:

输入/输出格式规范: -f, --from-code=名称 原始文本编码 -t, --to-code=名称 输出编码 信息: -l, --list 列举所有已知的字符集 输出控制: -c 从输出中忽略无效的字符 -o, --output=FILE 输出文件 -s, --silent 关闭警告 --verbose 打印进度信息

示例:下面的命令是将一个utf8编码的文件转换为一个unicode编码的文件

iconv -f utf-8 -t gb2312 utf8file.txt -o gb2312file.txt C语言调用iconv库 下载libiconv库 根据个人开发板,交叉编译出动态库。 Ubuntu下好像可以直接包含头文件使用。 #include

三个主要函数:

iconv_t iconv_open(const char *tocode, const char *fromcode);

此函数说明将要进行哪两种编码的转换,tocode是目标编码,fromcode是原编码,该函数返回一个转换句柄,供以下两个函数使用。

size_t iconv(iconv_t cd,char **inbuf,size_t *inbytesleft,char **outbuf,size_t *outbytesleft);

此函数从inbuf中读取字符,转换后输出到outbuf中,inbytesleft用以记录还未转换的字符数,outbytesleft用以记录输出缓冲的剩余空间。

注意:inbuf和outbuf都必须是有存储空间的不能定义为常量,如:char *inbuf = “abc” 或者是char *outbuf = "123"这样定义都是错误的。另外inbuf,inbytesleft,outbuf,outbytesleft这几个参数在使用过程中都会改变,最好是先保存一下原值,然后再使用。

int iconv_close(iconv_t cd);

此函数用于关闭转换句柄,释放资源。

代码示例:

#include #include #include #include "iconv.h" //iInLen的长度不包括\0,应该用strlen。返回值是处理后的sOut长度 static int Utf8ToGb2312(char *sOut, int iMaxOutLen, const char *sIn, int iInLen) { char *pIn = (char *)sIn; char *pOut = sOut; size_t ret; size_t iLeftLen=iMaxOutLen; iconv_t cd; cd = iconv_open("gb2312", "utf-8"); if (cd == (iconv_t) - 1) { return -1; } size_t iSrcLen=iInLen; ret = iconv(cd, &pIn,&iSrcLen, &pOut,&iLeftLen); if (ret == (size_t) - 1) { iconv_close(cd); return -1; } iconv_close(cd); return (iMaxOutLen - iLeftLen); } //iInLen的长度不包括\0,应该用strlen。返回值是处理后的sOut长度 static int Gb2312ToUtf8(char *sOut, int iMaxOutLen, const char *sIn, int iInLen) { char *pIn = (char *)sIn; char *pOut = sOut; size_t ret; size_t iLeftLen=iMaxOutLen; iconv_t cd; cd = iconv_open("utf-8", "gb2312"); if (cd == (iconv_t) - 1) { return -1; } size_t iSrcLen=iInLen; ret = iconv(cd, &pIn,&iSrcLen, &pOut,&iLeftLen); if (ret == (size_t) - 1) { iconv_close(cd); return -1; } iconv_close(cd); return (iMaxOutLen - iLeftLen); } int main() { int nRtn = 0; char* pszOri = "这是一个中文测试例程"; printf("byStr[%d]: %s\n", strlen(pszOri), pszOri); char pszDst[50] = {0}; int iLen = Utf8ToGb2312(pszDst, 50, pszOri, strlen(pszOri)); // Utf8ToGb2312 printf("iLen: %d %s\n", iLen, pszDst); printf("-----------\n"); char pszGbDst[50] = {0}; int iNewLen = Gb2312ToUtf8(pszGbDst, 50, pszDst, iLen); // Gb2312ToUtf8 printf("iNewLen: %d %s\n", iNewLen, pszGbDst); return nRtn; }

以上代码在Linux下编译,记得加上-liconv,代码先将UTF-8转换为GB2312,再从GB2312转为UTF-8,在SecureCRT下,按照GB2312编码方式显示,可以看到iLen后面的中文打印,按照UTF-8编码方式打印,可以看到byStr以及iNewLen后面的中文打印。

参考:Linux下 GB2312和UTF8转换接口



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有